package com.etone.autotesting.conditions;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.etone.autotesting.conditions.base.CommonCondition;
import com.etone.ejb.core.support.Jsoner;

public class ObjectCondition extends CommonCondition {

	private List<CommonCondition> noFixedCondition;
	private List<CommonCondition> fixedCondition;
	private String condition;
	private String page;
	private String filter;
	private String order;
	private double fixedLength = 0;
	private double curConditionIndex = 1;
	private Integer fixedConLength = 0;

	/**
	 * @param condition
	 *            the condition to set
	 */
	public void setCondition(String condition) {
		this.condition = condition;
		initCondition();
	}

	/**
	 * @return the condition
	 */
	public String getCondition() {
		return condition;
	}

	/**
	 * @return the page
	 */
	public String getPage() {
		return page;
	}

	/**
	 * @param page
	 *            the page to set
	 */
	public void setPage(String page) {
		this.page = page;
	}

	/**
	 * @return the filter
	 */
	public String getFilter() {
		return filter;
	}

	/**
	 * @param filter
	 *            the filter to set
	 */
	public void setFilter(String filter) {
		this.filter = filter;
	}

	/**
	 * @return the order
	 */
	public String getOrder() {
		return order;
	}

	/**
	 * @param order
	 *            the order to set
	 */
	public void setOrder(String order) {
		this.order = order;
	}

	public void setCurConditionIndex(Integer index) {
		this.curConditionIndex = index;
	}

	/**
	 * 
 	*/
	private void initCondition() {
		curIndex = 0;
		noFixedCondition = new ArrayList<CommonCondition>();
		fixedCondition = new ArrayList<CommonCondition>();
		Jsoner query = new Jsoner("{condition:" + condition + "}");
		List<Map> allCondition = query.root().get("condition").getArray();
		for (Map condi : allCondition) {
			String type = condi.get("type").toString();
			String name = condi.get("name").toString();
			List<Object> keyCondition = (List<Object>) condi.get("value");
			Boolean isNeed = (Boolean) condi.get("isNeed");
			CommonCondition addCondition = null;
			if ("TIME".equals(type)) {
				addCondition = new TimeCondition();
			} else if ("LIST".equals(type)) {
				addCondition = new ListCondition();
			} else if ("VALUE".equals(type)) {
				addCondition = new ValueConditon();
			}
			addCondition.setConditionKey(name);
			addCondition.setConditionList(keyCondition);
			if (isNeed) {
				fixedCondition.add(addCondition);
				if (fixedLength != 0)
					fixedLength *= addCondition.getJoinLength();
				else
					fixedLength = addCondition.getJoinLength();
			} else
				noFixedCondition.add(addCondition);
		}
		listLength = noFixedCondition.size();
		this.length = Math.pow(2, listLength) - 1;
		fixedConLength = fixedCondition.size();
	}

	@Override
	public String getJsonCondition() {		
		String curComString = "";
		if (curIndex < length + 1) {
			if (curIndex > 0 && fixedConLength + curIndex != fixedCondition.size()) {
				curComString = getIndexString(0, 0);
				Integer stringLength = curComString.length();
				char[] charArray = curComString.toCharArray();
				for (int i = 0; i < stringLength; i++) {
					Integer curChar = Integer.parseInt(String.valueOf(charArray[i]));
					fixedCondition.add(noFixedCondition.get(curChar));
				}
				fixedLength = 0;
				for (CommonCondition condi : fixedCondition)
					if (fixedLength != 0)
						fixedLength *= condi.getJoinLength();
					else
						fixedLength = condi.getJoinLength();
				curConditionIndex = 1;
			}
			curComString = getIndexCondition(0, 0);
			curConditionIndex++;
			//return curComString;
			String[] charArray = curComString.split("\\,");
			Integer stringLength = charArray.length;
			StringBuilder conditionBuilder = new StringBuilder();
			for (int i = 0; i < stringLength; i++) {
				Integer curChar = Integer.parseInt(String.valueOf(charArray[i]));
				fixedCondition.get(i).setCurIndex(curChar);
				String fixedConditionValue = fixedCondition.get(i).getJsonCondition();
				conditionBuilder.append(fixedConditionValue + ",");
			}
			conditionBuilder.deleteCharAt(conditionBuilder.length() - 1);
			curComString = "{" + conditionBuilder.toString() + "}";
			if (curConditionIndex > fixedLength)
				curIndex++;
		}
		Jsoner query = new Jsoner(curComString);
		page = query.root().get("page").toString();
		order = query.root().get("order").toString();
		filter = curComString;
		return curComString;
	}

	/**
	 * 获取总长度
	 */
	@Override
	public double getJoinLength() {
		double totalLength = fixedLength;
		double keepIndex = curIndex;
		curIndex = 1;
		for (int i = 0; i < length; i++) {
			StringBuilder builder = new StringBuilder("0");
			String curComString = getIndexString(0, 0);
			String[] charArray = curComString.split("\\,"); //curComString.toCharArray();
			Integer stringLength = charArray.length;
			double evenyLength = fixedLength;
			for (int j = 0; j < stringLength; j++) {
				Integer curChar = Integer.parseInt(String.valueOf(charArray[j]));
				evenyLength *= noFixedCondition.get(curChar).getJoinLength();
			}
			totalLength += evenyLength;
		}
		curIndex = keepIndex;
		length = totalLength;
		return totalLength;
	}
/**
 * 
 * @param searchLength
 * @param builder
 * @param searchIndex
 * @return
 */
	protected String getIndexCondition(double searchLength, Integer... searchIndex) {
		double curLength = 0;
		int curFixedConLength = fixedCondition.size();
		int searchIndexLength = searchIndex.length;
		int lastSearchIndexValue = searchIndex[searchIndexLength - 1];
		if (searchIndexLength < curFixedConLength)
			for (int i = searchIndexLength; i < curFixedConLength; i++) {
				if (curLength == 0)
					curLength = fixedCondition.get(i).getJoinLength();
				else
					curLength *= fixedCondition.get(i).getJoinLength();
			}
		else {
			curLength += 1;			
		}
		curLength += searchLength;
		if (curConditionIndex > curLength) {
			int nextIndexValue = lastSearchIndexValue + 1;			
			searchIndex[searchIndexLength - 1] = nextIndexValue;
			return getIndexCondition(curLength , searchIndex);
		} else {
			if (curLength == curConditionIndex && curFixedConLength == searchIndexLength){
				StringBuilder builder = new StringBuilder();
				for(Integer value : searchIndex)
					builder.append(value+",");
				builder.deleteCharAt(builder.length()-1);
				return builder.toString();
			}
			int nextIndexValue = 0;
			List<Integer> list = new ArrayList<Integer>();
			for (Integer ier : searchIndex)
				list.add(ier);
			list.add(nextIndexValue);
			return getIndexCondition(searchLength, list.toArray(new Integer[0]));
		}
	}
}
